package com.nami.framework.security.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.nami.common.domain.pojo.SysMenu;
import com.nami.common.domain.pojo.SysRole;
import com.nami.common.domain.pojo.SysUser;
import com.nami.system.service.ISysMenuService;
import com.nami.system.service.ISysRoleService;
import com.nami.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 验证用户信息
 *
 * @author C
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final ISysUserService userService;

    private final ISysRoleService roleService;

    private final ISysMenuService menuService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = userService.getUserByName(username);
        if (ObjectUtil.isEmpty(user)) {
            throw new UsernameNotFoundException("用户不存在!");
        }
        // 获取用户的角色集合
        List<SysRole> roles = roleService.getRolesByUserId(user.getId());
        if (!ObjectUtil.isEmpty(roles)) {
            List<String> roleKeys = buildRoleKeys(roles);
            user.setRoleKeys(roleKeys);
            // 获取用户的权限集合
            List<Long> roleIds = roles.stream().map(SysRole::getId).distinct().collect(Collectors.toList());
            List<SysMenu> menus = menuService.getMenuByRoleIds(roleIds);
            log.info("菜单集合信息: {}", JSONObject.toJSONString(menus));
            List<String> perms = buildMenusPerms(menus);
            log.info("用户的权限集合: {}", perms);
            user.setPerms(perms);
        }
        return user;
    }

    /**
     * 根据菜单集合获取权限集合
     *
     * @param menus 菜单集合
     * @return 权限集合
     */
    private List<String> buildMenusPerms(List<SysMenu> menus) {
        if (ObjectUtil.isEmpty(menus)) {
            return null;
        }
        return menus.stream().filter(item -> StringUtils.isNotEmpty(item.getPerms())).map(SysMenu::getPerms).distinct().collect(Collectors.toList());
    }

    /**
     * 根据角色集合生成角色字符结合
     *
     * @param roles 角色信息集合
     * @return 角色字符集合
     */
    private List<String> buildRoleKeys(List<SysRole> roles) {
        if (ObjectUtil.isEmpty(roles)) {
            return null;
        }
        return roles.stream().map(SysRole::getRoleKey).distinct().collect(Collectors.toList());
    }
}
